<template>
  <div class="app-container">
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>设备状态监控</span>
          <div class="header-right">
            <el-input v-model="deviceNo" placeholder="请输入设备编号" style="width: 200px" class="filter-item" @keyup.enter="handleQuery" />
            <el-button type="primary" @click="handleQuery">查询</el-button>
            <el-switch v-model="autoRefresh" active-text="自动刷新" inactive-text="手动刷新" @change="handleAutoRefreshChange" />
            <span v-if="autoRefresh" class="refresh-time">上次更新: {{ lastRefreshTime }}</span>
          </div>
        </div>
      </template>

      <!-- 实时数据展示 -->
      <el-row :gutter="20" class="data-overview">
        <el-col :span="6">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>温度</span>
              </div>
            </template>
            <div class="data-value">
              <span class="value">{{ currentStatus.temperature || '--' }}</span>
              <span class="unit">°C</span>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>湿度</span>
              </div>
            </template>
            <div class="data-value">
              <span class="value">{{ currentStatus.humidity || '--' }}</span>
              <span class="unit">%</span>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>信号强度</span>
              </div>
            </template>
            <div class="data-value">
              <span class="value">{{ currentStatus.signalStrength || '--' }}</span>
              <span class="unit">%</span>
            </div>
          </el-card>
        </el-col>
        <el-col :span="6">
          <el-card shadow="hover">
            <template #header>
              <div class="card-header">
                <span>更新时间</span>
              </div>
            </template>
            <div class="data-value">
              <span class="value">{{ formatTime(currentStatus.createTime) }}</span>
            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- 历史数据图表 -->
      <div class="chart-container">
        <el-card>
          <template #header>
            <div class="card-header">
              <span>历史数据趋势</span>
              <el-date-picker
                v-model="dateRange"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                @change="handleDateRangeChange"
              />
            </div>
          </template>
          <div ref="chartRef" style="width: 100%; height: 400px"></div>
        </el-card>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { ElMessage } from 'element-plus';
import * as echarts from 'echarts';
import { getDeviceStatus, getDeviceHistory } from '@/api/vending/deviceStatus';
import { parseTime } from '@/utils/ruoyi';
import { useRouter, onBeforeRouteLeave } from 'vue-router';

// 定义设备状态接口
interface DeviceStatus {
  temperature: number | null;
  humidity: number | null;
  signalStrength: number | null;
  createTime: string | null;
  deviceNo: string;
}

const deviceNo = ref('');
const currentStatus = ref<DeviceStatus>({
  temperature: null,
  humidity: null,
  signalStrength: null,
  createTime: null,
  deviceNo: ''
});
const dateRange = ref([]);
const chartRef = ref(null);
let chart = null;
let timer = null;

// 自动刷新相关状态
const autoRefresh = ref(false);
const lastRefreshTime = ref('--');
const refreshInterval = ref(1000); // 默认30秒刷新一次

// 初始化图表
const initChart = () => {
  if (chartRef.value) {
    chart = echarts.init(chartRef.value);
  }
};

// 数据采样函数
const sampleData = (data: any[], threshold = 0.3) => {
  if (data.length <= 2) return data;

  const result = [data[0]]; // 保留第一个点
  let lastPoint = data[0];
  let lastSignificantPoint = data[0];

  for (let i = 1; i < data.length - 1; i++) {
    const currentPoint = data[i];
    const nextPoint = data[i + 1];

    // 计算当前点与上一个显著点的变化率
    const tempChange = Math.abs((currentPoint.temperature - lastSignificantPoint.temperature) / (lastSignificantPoint.temperature || 1));
    const humidityChange = Math.abs((currentPoint.humidity - lastSignificantPoint.humidity) / (lastSignificantPoint.humidity || 1));
    const signalChange = Math.abs((currentPoint.signalStrength - lastSignificantPoint.signalStrength) / (lastSignificantPoint.signalStrength || 1));

    // 如果任一指标变化超过阈值，保留该点
    if (tempChange > threshold || humidityChange > threshold || signalChange > threshold) {
      result.push(currentPoint);
      lastSignificantPoint = currentPoint;
    }

    lastPoint = currentPoint;
  }

  result.push(data[data.length - 1]); // 保留最后一个点
  return result;
};

// 更新图表数据
const updateChart = (data) => {
  if (!chart) return;

  // 对数据进行采样
  const sampledData = sampleData(data);

  const option = {
    backgroundColor: '#ffffff',
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(255, 255, 255, 0.9)',
      borderColor: '#eee',
      borderWidth: 1,
      textStyle: {
        color: '#333'
      },
      formatter: (params) => {
        const time = parseTime(params[0].value[0]);
        let result = `<div style="font-weight: bold; margin-bottom: 5px;">${time}</div>`;
        params.forEach((param) => {
          const value = param.value[1];
          const unit = param.seriesName === '信号强度' ? '%' : param.seriesName === '温度' ? '°C' : '%';
          result += `<div style="display: flex; align-items: center; margin: 3px 0;">
            <span style="display: inline-block; width: 10px; height: 10px; background: ${param.color}; margin-right: 5px;"></span>
            <span style="flex: 1;">${param.seriesName}:</span>
            <span style="font-weight: bold; margin-left: 10px;">${value}${unit}</span>
          </div>`;
        });
        return result;
      }
    },
    legend: {
      data: ['温度', '湿度', '信号强度'],
      top: 10,
      textStyle: {
        color: '#666'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      top: '60px',
      containLabel: true
    },
    xAxis: {
      type: 'time',
      axisLine: {
        lineStyle: {
          color: '#ddd'
        }
      },
      axisLabel: {
        color: '#666',
        formatter: (value) => {
          return parseTime(value);
        }
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#eee'
        }
      }
    },
    yAxis: [
      {
        type: 'value',
        name: '温度/湿度',
        position: 'left',
        axisLine: {
          lineStyle: {
            color: '#ddd'
          }
        },
        axisLabel: {
          color: '#666',
          formatter: '{value}'
        },
        splitLine: {
          lineStyle: {
            color: '#eee'
          }
        }
      },
      {
        type: 'value',
        name: '信号强度',
        position: 'right',
        max: 100,
        axisLine: {
          lineStyle: {
            color: '#ddd'
          }
        },
        axisLabel: {
          color: '#666',
          formatter: '{value}%'
        },
        splitLine: {
          show: false
        }
      }
    ],
    series: [
      {
        name: '温度',
        type: 'line',
        smooth: true,
        showSymbol: false,
        sampling: 'average',
        data: sampledData.map((item) => [item.createTime, item.temperature]),
        itemStyle: {
          color: '#F56C6C'
        },
        lineStyle: {
          width: 2
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(245, 108, 108, 0.3)' },
            { offset: 1, color: 'rgba(245, 108, 108, 0.1)' }
          ])
        }
      },
      {
        name: '湿度',
        type: 'line',
        smooth: true,
        showSymbol: false,
        sampling: 'average',
        data: sampledData.map((item) => [item.createTime, item.humidity]),
        itemStyle: {
          color: '#409EFF'
        },
        lineStyle: {
          width: 2
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(64, 158, 255, 0.3)' },
            { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
          ])
        }
      },
      {
        name: '信号强度',
        type: 'line',
        smooth: true,
        showSymbol: false,
        sampling: 'average',
        yAxisIndex: 1,
        data: sampledData.map((item) => [item.createTime, item.signalStrength]),
        itemStyle: {
          color: '#67C23A'
        },
        lineStyle: {
          width: 2
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(103, 194, 58, 0.3)' },
            { offset: 1, color: 'rgba(103, 194, 58, 0.1)' }
          ])
        }
      }
    ]
  };

  chart.setOption(option);
};

// 更新最后刷新时间
const updateLastRefreshTime = () => {
  lastRefreshTime.value = parseTime(new Date());
};

// 停止定时器
const stopTimer = () => {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
};

// 定时刷新数据
const startTimer = () => {
  stopTimer(); // 先清除可能存在的定时器
  if (deviceNo.value) {
    handleQuery(); // 立即执行一次查询
    timer = setInterval(() => {
      if (deviceNo.value) {
        handleQuery();
      }
    }, refreshInterval.value);
  }
};

// 处理自动刷新开关变化
const handleAutoRefreshChange = (value: boolean) => {
  if (value) {
    startTimer();
  } else {
    stopTimer();
  }
};

// 修改查询函数
const handleQuery = async () => {
  if (!deviceNo.value) {
    ElMessage.warning('请输入设备编号');
    return;
  }

  try {
    const res = await getDeviceStatus(deviceNo.value);
    // console.log(res)
    if (res.code === 200 && res.data.length > 0) {
      const latestData = res.data[res.data.length - 1];
      currentStatus.value = {
        temperature: latestData.temperature?.toFixed(2) || '--',
        humidity: latestData.humidity?.toFixed(2) || '--',
        signalStrength: latestData.signalStrength || '--',
        createTime: latestData.createTime || new Date().toISOString(),
        deviceNo: latestData.deviceNo
      };
      updateLastRefreshTime(); // 更新最后刷新时间
    }
  } catch (error) {
    console.error('获取设备状态失败:', error);
    ElMessage.error('获取设备状态失败');
  }
};

// 查询历史数据
const handleDateRangeChange = async () => {
  if (!deviceNo.value || !dateRange.value) return;

  try {
    const [start, end] = dateRange.value;
    const res = await getDeviceHistory(deviceNo.value, start.getTime(), end.getTime());
    if (res.code === 200) {
      // 处理数据，确保数值类型正确
      const processedData = res.data.map((item) => ({
        ...item,
        temperature: Number(item.temperature?.toFixed(2)) || 0,
        humidity: Number(item.humidity?.toFixed(2)) || 0,
        signalStrength: Number(item.signalStrength) || 0,
        createTime: item.createTime || new Date().toISOString()
      }));

      // 按时间排序
      processedData.sort((a, b) => new Date(a.createTime).getTime() - new Date(b.createTime).getTime());

      // 如果数据点太多，进行降采样
      if (processedData.length > 1000) {
        const step = Math.ceil(processedData.length / 1000);
        const sampledData = [];
        for (let i = 0; i < processedData.length; i += step) {
          sampledData.push(processedData[i]);
        }
        updateChart(sampledData);
      } else {
        updateChart(processedData);
      }
    }
  } catch (error) {
    console.error('获取历史数据失败:', error);
    ElMessage.error('获取历史数据失败');
  }
};

// 格式化时间
const formatTime = (time) => {
  if (!time) return '--';
  return parseTime(time);
};

// 组件挂载时启动定时器
onMounted(() => {
  initChart();
  if (autoRefresh.value) {
    startTimer();
  }

  // 添加页面刷新和关闭事件监听
  window.addEventListener('beforeunload', stopTimer);
});

// 组件卸载时清理定时器
onUnmounted(() => {
  stopTimer();
  if (chart) {
    chart.dispose();
  }
  // 移除事件监听
  window.removeEventListener('beforeunload', stopTimer);
});

// 路由离开守卫
onBeforeRouteLeave((to, from, next) => {
  stopTimer();
  next();
});
</script>

<style scoped>
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.data-overview {
  margin-bottom: 20px;
}

.data-value {
  text-align: center;
  padding: 10px 0;
}

.data-value .value {
  font-size: 24px;
  font-weight: bold;
  color: #409eff;
}

.data-value .unit {
  font-size: 14px;
  color: #909399;
  margin-left: 5px;
}

.chart-container {
  margin-top: 20px;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.refresh-time {
  color: #909399;
  font-size: 13px;
  margin-left: 8px;
}

.el-switch {
  margin: 0 12px;
}

/* 添加响应式样式 */
@media screen and (max-width: 768px) {
  .card-header {
    flex-direction: column;
    gap: 12px;
  }

  .header-right {
    width: 100%;
    flex-wrap: wrap;
    justify-content: space-between;
  }

  .el-input {
    width: 100% !important;
    margin-bottom: 8px;
  }

  .refresh-time {
    width: 100%;
    text-align: right;
    margin-top: 8px;
  }
}

.device-option {
  padding: 6px 0 4px 0;
  min-width: 260px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.device-row1 {
  display: flex;
  align-items: center;
  font-size: 14px;
  font-weight: 600;
  color: #222;
  line-height: 20px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.device-name {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.device-no {
  font-size: 12px;
  color: #b0b0b0;
  font-weight: 400;
  margin-left: 8px;
  max-width: 90px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.device-row2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  min-height: 20px;
}

.device-tag {
  height: 18px;
  line-height: 16px;
  font-size: 11px;
  padding: 0 8px;
  border-radius: 8px;
  background: #f4f8fb;
  color: #409eff;
  border: none;
  white-space: nowrap;
}

:deep(.el-select-dropdown__item) {
  padding: 4px 12px;
  height: auto;
  min-height: unset;
  line-height: normal;
  text-align: left;
  transition: background 0.2s;
  border-radius: 6px;
  margin: 2px 0;
  &:hover,
  &.hover {
    background: #f0f7ff;
  }
  &.selected {
    background: #e6f7ff;
    .device-row1 {
      color: #409eff;
    }
  }
}
</style>
